//
//  DemoNSCoding.swift
//  swiftDemo
//
//  Created by JIENING ZHANG on 2020/10/29.
//  Copyright © 2020 lovivid. All rights reserved.
//

import UIKit
/*
 https://www.jianshu.com/p/4876e94862e2
 
 NSCoding
    这个协议在Cocoa的Foundation框架中定义，内置的大多数Cocoa类都采用了NSCoding协议，比如 UIColor 等。
    采用了这个协议的对象可以转换为 NSData 类型，然后再转换回来。使用 NSKeyedArchiver 和 NSKeyedUnarchiver 分别进行归档和解档。
    采用这个协议的对象需要实现 encode(with:) 进行归档，以及 init(coder:) 进行解档。
    在 iOS12中，苹果推荐使用 NSSecureCoding 协议，这个协议在NSCoding的基础上，还需要实现一个静态的 supportsSecureCoding 属性
        static var supportsSecureCoding: Bool {return true}


 Codable
    这个是swift4.0中引入的新协议，主要是为了解决数据（比如JSON）序列化问题。它实际上是 Encodable 和 Decodable 协议的结合.
    使用Codable的对象，类实例，结构体实例，枚举实例（RawRepresentable 类型的枚举，即拥有 raw value）等都可以被编码
    任何对象只要遵守Encodable协议，都可以被序列化（归档），任何遵循Decodable协议的对象都可以从序列化形式恢复（解档）。

    存在3种形式的序列化模式：
        property list:  使用 PropertyListEncoder 的 encode(_:) 进行编码，使用 PropertyListDecoder 的 decode(_:from:) 进行解码
        JSON:           使用 JSONEncoder 的 encode(_:) 进行编码，使用 JSONDecoder 的 decode(_:from:) 进行解码
        NSCoder:        使用 NSKeyedArchiverEncoder 的 encodeEncodable(_:forKey:) 进行编码，使用 NSKeyedUnarchiverDecoder 的 decodeDecodable(_:forKey:) 进行解码
     
    大多数内置的Swift类型都是默认的Codable，encode(to:) 和 init(from:) 类似于 NSCoding中的 encode(with:) 和 init(coder:), 但是通常不需要我们去实现，因为通过扩展协议的方式，提供了默认的实现

 */

class DemoNSCoding: NSObject,NSCoding {

    var name:String?;
    var cDate:Date?;
    var binData:Data?;
    var info:Dictionary<String, Any>?;
    var children:Array<Any>?;
    
    func encode(with coder: NSCoder) {
        if self.name != nil {
            coder.encode(self.name,         forKey: "name")
        }
        
        if self.cDate != nil {
            coder.encode(self.cDate,        forKey: "cDate")
        }
        
        if self.binData != nil {
            coder.encode(self.binData,      forKey: "binData")
        }
        
        if self.info != nil {
            coder.encode(self.info,         forKey: "info")
        }
        
        if self.children != nil {
            coder.encode(self.children,     forKey: "children")
        }
    }
    
    override init() {
        super.init()
    }
    
    required init?(coder: NSCoder) {
        self.name =     coder.decodeObject(forKey: "name") as? String
        self.cDate =    coder.decodeObject(forKey: "cDate") as? Date
        self.binData =  coder.decodeObject(forKey: "binData") as? Data
        self.info =     coder.decodeObject(forKey: "info") as? Dictionary<String, Any>
        self.children = coder.decodeObject(forKey: "children") as? Array<Any>
    }
    
    override var description : String {
        "name : \(name), cDate : \(cDate),  binData:\(binData), info:\(info), children:\(children)"
    }
}
